class ConfigTool {
  static remoteBaseUrl = "https://api.example.com";
  static dbName = 'GamepadConfigDB';
  static storeName = 'configs';
  static version = 1;
  static dbInstance = null;

  /**
   * 打开IndexedDB数据库
   * @returns {Promise<IDBDatabase>} 数据库实例
   */
  static async openDB() {
    if (ConfigTool.dbInstance) {
      return ConfigTool.dbInstance;
    }

    return new Promise((resolve, reject) => {
      const request = indexedDB.open(ConfigTool.dbName, ConfigTool.version);

      // 数据库版本升级时创建对象存储
      request.onupgradeneeded = (event) => {
        const db = event.target.result;
        if (!db.objectStoreNames.contains(ConfigTool.storeName)) {
          db.createObjectStore(ConfigTool.storeName, { keyPath: 'id' });
        }
      };

      request.onsuccess = (event) => {
        ConfigTool.dbInstance = event.target.result;
        // 监听数据库关闭事件，清除缓存
        ConfigTool.dbInstance.onclose = () => {
          ConfigTool.dbInstance = null;
        };
        resolve(ConfigTool.dbInstance);
      };
      request.onerror = (event) => reject(event.target.error);
    });
  }

  /**
   * 从本地IndexedDB读取配置
   * @param {string} configId 配置ID，默认为'default'
   * @returns {Promise<Object|null>} 配置数据
   */
  static async getLocalConfig(configId = 'default') {
    const db = await ConfigTool.openDB();
    return new Promise((resolve, reject) => {
      const transaction = db.transaction(ConfigTool.storeName, 'readonly');
      const store = transaction.objectStore(ConfigTool.storeName);
      const request = store.get(configId);

      request.onsuccess = () => resolve(request.result?.data || null);
      request.onerror = () => reject(request.target.error);
    });
  }

  /**
   * 保存配置到本地IndexedDB
   * @param {Object} configData 要保存的配置数据
   * @param {string} configId 配置ID，默认为'default'
   * @returns {Promise<boolean>} 保存成功返回true
   */
  static async saveLocalConfig(configData, configId = 'default') {
    const db = await ConfigTool.openDB();
    return new Promise((resolve, reject) => {
      const transaction = db.transaction(ConfigTool.storeName, 'readwrite');
      const store = transaction.objectStore(ConfigTool.storeName);
      const request = store.put({ id: configId, data: configData });

      request.onsuccess = () => resolve(true);
      request.onerror = () => reject(request.target.error);
    });
  }

  /**
   * 从远程服务器读取配置
   * @param {string} configId 配置ID
   * @returns {Promise<Object>} 远程配置数据
   */
  static async getRemoteConfig(configId) {
    if (!ConfigTool.remoteBaseUrl) {
      throw new Error('远程服务器URL未配置');
    }

    try {
      const response = await fetch(`${ConfigTool.remoteBaseUrl}/config/${configId}`);
      if (!response.ok) {
        throw new Error(`HTTP错误: ${response.status}`);
      }
      return await response.json();
    } catch (error) {
      console.error(`读取远程配置[${configId}]失败:`, error);
      throw new Error(`读取远程配置[${configId}]失败: ${error.message}`);
    }
  }

  /**
   * 保存配置到远程服务器
   * @param {Object} configData 要保存的配置数据
   * @param {string} configId 配置ID
   * @returns {Promise<Object>} 服务器响应
   */
  static async saveRemoteConfig(configData, configId) {
    if (!ConfigTool.remoteBaseUrl) {
      throw new Error('远程服务器URL未配置');
    }

    try {
      const response = await fetch(`${ConfigTool.remoteBaseUrl}/config/${configId}`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(configData),
      });

      if (!response.ok) {
        throw new Error(`HTTP错误: ${response.status}`);
      }
      return await response.json();
    } catch (error) {
      console.error(`保存远程配置[${configId}]失败:`, error);
      throw new Error(`保存远程配置[${configId}]失败: ${error.message}`);
    }
  }

  /**
   * 获取游戏配置（优先本地，本地不存在则从远程加载）
   * @param {string} configId 配置ID，默认为'default'
   * @returns {Promise<Object|null>} 配置数据
   */
  /**
   * 验证配置ID格式
   * @param {string} configId - 配置ID
   * @throws {TypeError} 如果configId不是字符串
   */
  static validateConfigId(configId) {
    if (typeof configId !== 'string') {
      throw new TypeError('configId必须是字符串');
    }
  }

  /**
   * 验证存储类型
   * @param {string} storageType - 存储类型
   * @param {string[]} allowedTypes - 允许的存储类型
   * @throws {TypeError} 如果storageType不在允许列表中
   */
  static validateStorageType(storageType, allowedTypes) {
    if (!allowedTypes.includes(storageType)) {
      throw new TypeError(`storageType必须是${allowedTypes.map(t => `"${t}"`).join('、')}`);
    }
  }

  /**
   * 获取游戏配置（优先本地，本地不存在则从远程加载）
   * @param {string} configId 配置ID，默认为'default'
   * @param {'auto'|'local'|'remote'} storageType 存储类型，默认为'auto'
   * @returns {Promise<Object|null>} 配置数据
   */
  static async getGameConfig(configId = 'default', storageType = 'auto') {
     this.validateConfigId(configId);
     this.validateStorageType(storageType, ['auto', 'local', 'remote']);
      if (storageType === 'local' || storageType === 'auto') {
        const localConfig = await this.getLocalConfig(configId);
        
        if (storageType === 'local') {
          return localConfig;
        } else if (localConfig) {
          return localConfig;
        }
      }
      
      // 如果是remote类型或auto类型且本地没有配置，则从远程获取
      const remoteConfig = await this.getRemoteConfig(configId);
      
      // 如果是auto类型，将远程配置保存到本地
      if (storageType === 'auto') {
        await this.saveLocalConfig(remoteConfig, configId);
      }
      
      return remoteConfig;
  }

  /**
   * 保存游戏配置到本地
   * @param {Object} configData 要保存的配置数据
   * @param {string} configId 配置ID，默认为'default'
   * @returns {Promise<boolean>} 保存成功返回true
   */
  /**
   * 保存游戏配置
   * @param {Object} configData 要保存的配置数据
   * @param {string} configId 配置ID，默认为'default'
   * @param {'local'|'remote'} storageType 存储类型，默认为'local'
   * @returns {Promise<boolean|Object>} 保存结果
   */
  static async saveGameConfig(configData, configId = 'default', storageType = 'local') {
     if (typeof configData !== 'object' || configData === null || Array.isArray(configData)) {
       throw new TypeError('configData必须是对象');
     }
     this.validateConfigId(configId);
     this.validateStorageType(storageType, ['local', 'remote']);
     if (storageType === 'local') {
       return this.saveLocalConfig(configData, configId);
     } else {
       return this.saveRemoteConfig(configData, configId);
     }
  }

  /**
   * 设置远程服务器基础URL
   * @param {string} url 服务器URL
   */
  static setRemoteBaseUrl(url) {
    ConfigTool.remoteBaseUrl = url;
  }
}

export const configService = {
  saveGameConfig: (configData, configId = 'default', storageType = 'local') => ConfigTool.saveGameConfig(configData, configId, storageType),
  getGameConfig: (configId = 'default', storageType = 'auto') => ConfigTool.getGameConfig(configId, storageType),
  setRemoteBaseUrl: (url) => ConfigTool.setRemoteBaseUrl(url)
};